package com.quick.develop.form.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.quick.develop.framework.common.page.PageResult;
import com.quick.develop.framework.common.service.impl.BaseServiceImpl;
import com.quick.develop.form.dao.GenDynamicFormFieldDao;
import com.quick.develop.form.entity.GenDynamicFormFieldEntity;
import com.quick.develop.form.query.GenDynamicFormFieldQuery;
import com.quick.develop.form.vo.FieldSortVO;
import com.quick.develop.form.vo.FormFieldBatchVO;
import com.quick.develop.form.vo.GenDynamicFormFieldVO;
import com.quick.develop.form.convert.GenDynamicFormFieldConvert;
import com.quick.develop.form.service.GenDynamicFormFieldService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 表单字段
 *
 * @author Tioo 1906559468@qq.com
 * @since 1.0.0 2023-09-24
 */
@Service(value = "genDynamicFormFieldServiceImpl")
@AllArgsConstructor
public class GenDynamicFormFieldServiceImpl extends BaseServiceImpl<GenDynamicFormFieldDao, GenDynamicFormFieldEntity> implements GenDynamicFormFieldService {

    @Override
    public PageResult<GenDynamicFormFieldVO> page(GenDynamicFormFieldQuery query) {
        IPage<GenDynamicFormFieldEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));

        return new PageResult<>(GenDynamicFormFieldConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
    }

    private LambdaQueryWrapper<GenDynamicFormFieldEntity> getWrapper(GenDynamicFormFieldQuery query) {
        LambdaQueryWrapper<GenDynamicFormFieldEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Objects.nonNull(query.getFormId()), GenDynamicFormFieldEntity::getFormId, query.getFormId());
        wrapper.like(StringUtils.isNotEmpty(query.getFieldKey()), GenDynamicFormFieldEntity::getFieldKey, query.getFieldKey());
        wrapper.like(StringUtils.isNotEmpty(query.getFieldNameZh()), GenDynamicFormFieldEntity::getFieldNameZh, query.getFieldNameZh());
        wrapper.like(StringUtils.isNotEmpty(query.getFieldNameCn()), GenDynamicFormFieldEntity::getFieldNameCn, query.getFieldNameCn());
        return wrapper;
    }

    @Override
    public void save(GenDynamicFormFieldVO vo) {
        GenDynamicFormFieldEntity entity = GenDynamicFormFieldConvert.INSTANCE.convert(vo);

        baseMapper.insert(entity);
    }

    @Override
    public void update(GenDynamicFormFieldVO vo) {
        GenDynamicFormFieldEntity entity = GenDynamicFormFieldConvert.INSTANCE.convert(vo);

        updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> idList) {
        removeByIds(idList);
    }

    @Override
    public List<GenDynamicFormFieldEntity> getFormElementsByGroupId(Integer id) {

        LambdaQueryWrapper<GenDynamicFormFieldEntity> wrapper = Wrappers.lambdaQuery(GenDynamicFormFieldEntity.class)
                .eq(GenDynamicFormFieldEntity::getGroupId, id)
                .orderByAsc(GenDynamicFormFieldEntity::getOrderNum);

        return Optional.ofNullable(list(wrapper))
                .orElse(new ArrayList<>());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchSave(FormFieldBatchVO batchVO) {
        Integer groupId = batchVO.getGroupId();
        int sort = (int) count(Wrappers.lambdaQuery(GenDynamicFormFieldEntity.class)
                .eq(GenDynamicFormFieldEntity::getGroupId, groupId));
        List<GenDynamicFormFieldEntity> fields = batchVO.getFields();
        for (GenDynamicFormFieldEntity sig : fields) {
            sig.setOrderNum(++sort);
            if (StringUtils.isBlank(sig.getAttributes())) {
                sig.setAttributes("{}");
            }
        }
        saveBatch(fields);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void exchangeOrder(FieldSortVO fieldSortVO) {
        GenDynamicFormFieldEntity source = getById(fieldSortVO.getSourceId());
        GenDynamicFormFieldEntity target = getById(fieldSortVO.getTargetId());
        Objects.requireNonNull(source);
        Objects.requireNonNull(target);

        Integer orderNum = source.getOrderNum();
        source.setOrderNum(target.getOrderNum());
        target.setOrderNum(orderNum);

        updateById(source);
        updateById(target);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchUpdate(FormFieldBatchVO batchVO) {
        if (CollUtil.isNotEmpty(batchVO.getFields())) {
            updateBatchById(batchVO.getFields());
        }
    }
}